package com.kaifamiao.session;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

/**
 * 用于执行 sql
 */
public class Execute {

    /**
     * 执行 sql
     * @param connection 数据库的连接
     * @param sql  sql语句
     * @param resultType  返回值类型
     * @param args   参数（占位符）
     * @param <T>
     * @return
     */
    public static <T> List<T> executeQuery(Connection connection, String sql, String resultType, Object... args) {
        List<T> list = new ArrayList<>();
        try {
            // 预处理 sql
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
            // 设置值(给占位符赋值
            if (args != null) {
                for (int i = 0; i < args.length; i++) {
                    preparedStatement.setObject(i + 1, args[i]);
                }
            }
            // 执行 sql
            ResultSet resultSet = preparedStatement.executeQuery();
            // 获取返回值类型的 Class 对象
            Class clazz = Class.forName(resultType);
            // 获取构造函数
            Constructor constructor = clazz.getDeclaredConstructor(null);
            // 获取结果集的元数据
            ResultSetMetaData metaData = resultSet.getMetaData();
            // 获取列数
            int columnCount = metaData.getColumnCount();

            // 迭代解析结果集
            while (resultSet.next()) {
                // 创建 clazz 类型的对象
                T object = (T) constructor.newInstance();
                // 迭代每一列
                for (int i = 1; i <= columnCount; i++) {
                    // 列名
                    String columnLabel = metaData.getColumnLabel(i);
                    // 获取值
                    Object value = resultSet.getObject(columnLabel);
                    // 处理属性名
                    if (columnLabel.startsWith("is_")) {
                        columnLabel.replace("is_", "");
                    }
                    if (columnLabel.contains("_")) {
                        // aaa_bbb_ccc aaa bbb ccc
                        String[] strings = columnLabel.split("_");
                        // stringBuilder = aaaBbbCcc
                        StringBuilder stringBuilder = new StringBuilder(strings[0]);
                        for (int j = 1; j < strings.length; j++) {
                            String current = strings[j];
                            stringBuilder.append(current.substring(0, 1).toUpperCase() + current.substring(1));
                        }
                        columnLabel = stringBuilder.toString();
                    }
                    // 设置对象对应的属性， java 内省机制
                    try {
                        // 获取对象的描述符
                        PropertyDescriptor propertyDescriptor = new PropertyDescriptor(columnLabel, clazz);
                        // 获取用于写入属性的方法 并执行方法
                        propertyDescriptor.getWriteMethod().invoke(object, value);
                    } catch (Exception e) {
                        System.err.println(e.getMessage());
                    }
                }
                // 添加到 list
                list.add(object);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return list;
    }
}
